﻿using AutoMapper;
using HikRcsService._631_Optical;
using HikRcsService.Common;
using HikRcsService.Models;
using Newtonsoft.Json;
using Serilog;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using WCS_Service.DomianService.Models;
using WCS_Service.Enums;
using WCS_Service.Models;
using WCS_Service.Models.SerialNetModel;
using WCS_Service.RcsServices.Interfaces;
using WCS_Utility.ConstString;

namespace WCS_Service.RcsServices
{
    public class HikOpticalRcsService : IHikOpticalRcsService
    {
        #region 事件
        public event Func<string, Task> HikRcsSendEvent;

        public event Func<RcsServiceResultModel, Task<string>> ServiceResultEvent;
        public event Func<string,string, object, string, Task> RcsReciveEvent;
        public event Func<string, string, Task> RollerReciveEvent;
        #endregion
        private readonly IMapper _mapper;
        #region 属性
        private readonly IHikParabuildService _hikParabuild;
        #endregion
        public async Task OrientedMsgAsync(string msg,int opticalId)
        {
            try
            {
                var info = JsonConvert.DeserializeObject<OpticalInfoModel>(msg);
                if (info is null || string.IsNullOrEmpty(info.funCode) || info.data.Length != info.dataLen)
                {
                    Log.Error($"光通信数据错误!");
                    return;
                }
                await RcsApiServiceAnalysis(info.funCode, info.type, info.data, info.number, opticalId.ToString());
            }
            catch (Exception ex)
            {
                Log.Error($"光通信数据转换失败!{ex.Message}");
                return;
            }
        }
        #region 
        /// <summary>
        /// 解析光通信接收的报文
        /// </summary>
        /// <param name="code"></param>
        /// <param name="msg"></param>
        /// <returns></returns>
        private async Task RcsApiServiceAnalysis(string code, OpticalMsgType type, string msg, string reqCode, string eqCode)
        {
            switch (type)
            {
                //光通信发的WCS访问RCS服务返回的数据
                case OpticalMsgType.Result:
                    await WCSResultProcessAsync(reqCode, code, type, msg, eqCode);
                    break;
                //光通讯发的RCS访问WCS的服务
                case OpticalMsgType.call:
                    await WCSServiceProcessAsync(code, type, msg, reqCode, eqCode);
                    break;
                //滚筒报文处理
                case OpticalMsgType.Roller:
                    await AGVRollerProcessAsync(reqCode, msg, eqCode);
                    break;
                //提示灯报文处理
                case OpticalMsgType.Promptlight:
                    await AGVPromptlightProcessAsync(reqCode, msg, eqCode);
                    break;
            }
        }
        #endregion

        #region 构造
        public HikOpticalRcsService(IHikParabuildService hikParabuild, IMapper mapper)
        {
            _hikParabuild = hikParabuild;
            _mapper = mapper;
        }
        #endregion

        #region 接收数据各个功能处理
        /// <summary>
        /// 指示灯报文
        /// </summary>
        /// <returns></returns>
        private async Task AGVPromptlightProcessAsync(string reqCode, string msg, string eqCode)
        {
            if (string.IsNullOrEmpty(msg))
            {
                Log.Error($"指示灯数据为空!");
                return;
            }
        }
        private async Task AGVRollerProcessAsync(string reqCode, string msg, string eqCode)
        {
            if (string.IsNullOrEmpty(msg))
            {
                Log.Error($"滚筒数据为空!");
                return;
            }

            RollerReciveEvent?.Invoke(eqCode,msg);
        }

        private async Task WCSResultProcessAsync(string reqCode, string code, OpticalMsgType type, string msg, string eqCode)
        {
            switch (code)
            {
                case OpticalFunCode.genAgvSchedulingTaskCode:
                case OpticalFunCode.bindCtnrAndBinCode:
                case OpticalFunCode.returnPodCode:
                case OpticalFunCode.boxApplyPassCode:
                    await ResultDataProcessAsync(msg, reqCode, code, eqCode);
                    break;
                //只返回访问成功或失败
                case OpticalFunCode.continueTaskCode:
                case OpticalFunCode.cancelTaskCode:
                case OpticalFunCode.setTaskPriorityCode:
                case OpticalFunCode.bindPodAndBerthCode:
                case OpticalFunCode.bindPodAndMatCode:
                case OpticalFunCode.lockPositionCode:
                case OpticalFunCode.blockStgBinCode:
                case OpticalFunCode.stopRobotCode:
                case OpticalFunCode.resumeRobotCode:
                case OpticalFunCode.blockAreaCode:
                case OpticalFunCode.clearRoadWayCode:
                case OpticalFunCode.getOutPodCode:
                case OpticalFunCode.genCtuGroupTaskBatchCode:
                    await ResultProcessAsync(msg, reqCode, eqCode);
                    break;
                case OpticalFunCode.syncMapDatasCode:
                    await ResultMapProcessAsync(msg, reqCode, eqCode);
                    break;
                case OpticalFunCode.queryPodBerthAndMatCode:
                    await ResultQueryPodBerthAndMat(msg, reqCode, eqCode);
                    break;
                case OpticalFunCode.queryTaskStatusCode:
                    await ResultQueryTaskStatus(msg, reqCode, eqCode);
                    break;
                case OpticalFunCode.queryAgvStatusCode:
                    await ResultQueryAgvStatus(msg, reqCode, eqCode);
                    break;
            }
        }

        private async Task WCSServiceProcessAsync(string code, OpticalMsgType type, string msg, string reqCode, string eqCode)
        {
            switch (code)
            {
                case OpticalFunCode.agvCallbackCode:
                    await Service_agvCallbackAsync(msg, eqCode);
                    break;
                case OpticalFunCode.bindNotifyCode: 
                    await Service_bindNotifyAsync(msg, eqCode);
                    break;
                case OpticalFunCode.applyReturnForValidCode:
                    await Service_applyReturnForValidAsync(msg, eqCode);
                    break;
                case OpticalFunCode.applyReturnForBinCode:
                    await Service_applyReturnForBinAsync(msg, eqCode);
                    break;
                case OpticalFunCode.warnCallbackCode:
                    await Service_warnCallback(msg, eqCode);
                    break;
                case OpticalFunCode.chargeRequestCode:
                    await Service__ChargeRequestAsync(msg, eqCode);
                    break;
            }
        }
        //充电请求
        private async Task Service__ChargeRequestAsync(string msg, string eqCode)
        {
            await Task.Run(() => 
            {
                var info = JsonConvert.DeserializeObject<ChargeRequestPara>(msg);
                if (info is null)
                {
                    Log.Error($"chargeRequest访问参数错误!");
                    return;
                }
                var data = _mapper.Map<ChargeRequestModel>(info);
                if (data is null)
                {
                    Log.Error($"chargeRequest参数转换错误!");
                    return;
                }
                RcsServiceResultModel model = new();
                model.apiName = HikRcsConst.chargeReport;
                model.eqCode = eqCode;
                model.info = data;
                if (ServiceResultEvent is null)
                {
                    Log.Error($"未绑定Rcs访问处理");
                    return;
                }
                ServiceResultEvent?.Invoke(model);
            });
        }

        //任务执行通知 报文处理
        private async Task Service_agvCallbackAsync(string msg, string eqCode)
        {
            await Task.Run(() => 
            {
                var info = JsonConvert.DeserializeObject<ExecuteResponsePara>(msg);
                if (info is null)
                {
                    Log.Error($"agvCallback访问参数错误!");
                    return;
                }
                var data = _mapper.Map<TaskExecuteStateModel>(info);
                if (data is null)
                {
                    Log.Error($"agvCallback参数转换错误!");
                    return;
                }
                RcsServiceResultModel model = new();
                model.apiName = HikRcsConst.agvCallback;
                model.eqCode = eqCode;
                model.info = data;
                if (ServiceResultEvent is null)
                {
                    Log.Error($"未绑定Rcs访问处理");
                    return;
                }
                ServiceResultEvent?.Invoke(model);
            });
        }
        //绑定解绑通知
        private async Task Service_bindNotifyAsync(string msg, string eqCode)
        {
            await Task.Run(() => 
            {
                var info = JsonConvert.DeserializeObject<BindNotifyPara>(msg);
                if (info is null)
                {
                    Log.Error($"绑定解绑通知访问参数错误!");
                    return;
                }
                var data = _mapper.Map<BindNotifyModel>(info);
                if (data is null)
                {
                    Log.Error($"绑定解绑通知访问参数转换错误!");
                    return;
                }
                RcsServiceResultModel model = new();
                model.apiName = HikRcsConst.bindNotify;
                model.eqCode = eqCode;
                model.info = data;
                if (ServiceResultEvent is null)
                {
                    Log.Error($"未绑定Rcs访问处理");
                    return;
                }
                ServiceResultEvent?.Invoke(model);
            });
        }
        //校验料箱是否可入库（CTU）
        private async Task Service_applyReturnForValidAsync(string msg, string eqCode)
        {
            await Task.Run(() => 
            {
                var info = JsonConvert.DeserializeObject<ApplyReturnForValidPara>(msg);
                if (info is null)
                {
                    Log.Error($"校验料箱是否可入库访问参数错误!");
                    return;
                }
                var data = _mapper.Map<ApplyReturnForValidModel>(info);
                if (data is null)
                {
                    Log.Error($"校验料箱是否可入库访问参数转换错误!");
                    return;
                }
                RcsServiceResultModel model = new();
                model.apiName = HikRcsConst.applyReturnForValid;
                model.eqCode = eqCode;
                model.info = data;
                if (ServiceResultEvent is null)
                {
                    Log.Error($"未绑定Rcs访问处理");
                    return;
                }
                ServiceResultEvent?.Invoke(model);
            });
        }
        //申请回库仓位（CTU） 
        private async Task Service_applyReturnForBinAsync(string msg, string eqCode)
        {
            var info = JsonConvert.DeserializeObject<ApplyReturnForBinPara>(msg);
            if (info is null)
            {
                Log.Error($"申请回库仓位访问参数错误!");
                return;
            }
            var data = _mapper.Map<ApplyReturnForBinModel>(info);
            if (data is null)
            {
                Log.Error($"申请回库仓位访问参数转换错误!");
                return;
            }
            RcsServiceResultModel model = new();
            model.apiName = HikRcsConst.applyReturnForBin;
            model.eqCode = eqCode;
            model.info = data;
            if (ServiceResultEvent is null)
            {
                Log.Error($"未绑定Rcs访问处理");
                return;
            }
            var resultInfo = await ServiceResultEvent?.Invoke(model);
        }
        //告警推送通知 
        private async Task Service_warnCallback(string msg, string eqCode)
        {
            await Task.Run(() => 
            {
                var info = JsonConvert.DeserializeObject<WarnPara>(msg);
                if (info is null)
                {
                    Log.Error($"告警访问参数错误!");
                    return;
                }
                var data = _mapper.Map<WarnModel>(info);
                if (data is null)
                {
                    Log.Error($"申请回库仓位访问参数转换错误!");
                    return;
                }
                RcsServiceResultModel model = new();
                model.apiName = HikRcsConst.warnCallback;
                model.eqCode = eqCode;
                model.info = data;
                ServiceResultEvent?.Invoke(model);
            });
        }
        #endregion

        #region 访问RCS服务后返回数据处理
        /// <summary>
        /// 查询AGV状态接口返回处理
        /// </summary>
        /// <param name="msg"></param>
        /// <param name="reqCode"></param>
        /// <returns></returns>
        private async Task ResultQueryAgvStatus(string msg, string reqCode, string eqCode)
        {
            await Task.Run(() => 
            {
                var info = JsonConvert.DeserializeObject<AgvStateResultPara>(msg);
                if (info is null)
                {
                    Log.Error($"查询AGV状态数据错误!");
                    return;
                }
                var data = _mapper.Map<AgvStateResultModel>(info);
                RcsReciveEvent?.Invoke(eqCode, data.reqCode, data, ConstStringData.RcsRecive_Agv);
            });
        }
        /// <summary>
        /// 查询任务状态接口返回处理
        /// </summary>
        /// <param name="msg"></param>
        /// <param name="reqCode"></param>
        /// <returns></returns>
        private async Task ResultQueryTaskStatus(string msg, string reqCode, string eqCode)
        {
            await Task.Run(() => 
            {
                var info = JsonConvert.DeserializeObject<QueryTaskStatusResultPara>(msg);
                if (info is null)
                {
                    Log.Error($"查询任务状态数据错误!");
                    return;
                }
                var data = _mapper.Map<QueryTaskStatusResultModel>(info);
                RcsReciveEvent?.Invoke(eqCode, data.reqCode, data, ConstStringData.RcsRecive_Task);
            });
        }
        /// <summary>
        /// 查询货架储位与物料批次关系接口
        /// </summary>
        /// <param name="msg"></param>
        /// <param name="reqCode"></param>
        /// <returns></returns>
        private async Task ResultQueryPodBerthAndMat(string msg, string reqCode, string eqCode)
        {
            await Task.Run(() => 
            {
                var info = JsonConvert.DeserializeObject<QueryPodBerthAndMatResultPara>(msg);
                if (info is null)
                {
                    Log.Error($"查询货架储位与物料批次关系数据错误!");
                    return;
                }
                var data = _mapper.Map<QueryPodBerthAndMatResultModel>(info);
                RcsReciveEvent?.Invoke(eqCode, data.reqCode, data, ConstStringData.RcsRecive_PodBerthAndMat);
            });
        }
        /// <summary>
        /// 地图同步上下文接口
        /// </summary>
        /// <param name="msg"></param>
        /// <param name="reqCode"></param>
        /// <returns></returns>
        private async Task ResultMapProcessAsync(string msg, string reqCode, string eqCode)
        {
            await Task.Run(() => 
            {
                var info = JsonConvert.DeserializeObject<SyncMapDatasResultPara>(msg);
                if (info is null)
                {
                    Log.Error($"地图信息数据错误!");
                    return;
                }
                var data = _mapper.Map<SyncMapDatasResultModel>(info);
                RcsReciveEvent?.Invoke(eqCode, data.reqCode, data, ConstStringData.RcsRecive_Map);
            });
        }
        private async Task ResultDataProcessAsync(string msg, string reqCode, string code, string eqCode)
        {
            await Task.Run(() => 
            {
                var info = JsonConvert.DeserializeObject<ResultDataPara>(msg);
                if (info is null)
                {
                    Log.Error($"ResultDataPara数据错误!");
                    return;
                }
                var data = _mapper.Map<ResultDataModel>(info);
                RcsReciveEvent?.Invoke(eqCode, info.reqCode, data, ConstStringData.RcsRecive_resultData);
            });
        }
        private async Task ResultProcessAsync(string msg, string reqCode, string eqCode)
        {
            await Task.Run(() => 
            {
                var info = JsonConvert.DeserializeObject<ResultPara>(msg);
                if (info is null)
                {
                    Log.Error($"ResultPara数据错误!");
                    return;
                }
                var data = _mapper.Map<ResultModel>(info);
                RcsReciveEvent?.Invoke(eqCode, info.reqCode, data, ConstStringData.RcsRecive_result);
            });
        }
        #endregion

        #region 访问RCS服务数据拼接
        public async Task<RcsServiceInfoModel> SplicingRCSParaAsync(string Api, object para)
        {
            RcsServiceInfoModel result = new RcsServiceInfoModel();
            var (info, reqCode) = Api switch
            {
                HikRcsConst.genAgvSchedulingTask => _hikParabuild.CreatTask(para),
                HikRcsConst.continueTask => _hikParabuild.CreatContinueTask(para),
                HikRcsConst.cancelTask => _hikParabuild.CreatCancelTask(para),
                HikRcsConst.queryTaskStatus => _hikParabuild.CreatQueryTaskStatus(para),
                HikRcsConst.queryAgvStatus => _hikParabuild.CreatQueryAgv(para),
                HikRcsConst.stopRobot => _hikParabuild.CreatStopAgv(para),
                HikRcsConst.resumeRobot => _hikParabuild.CreatRecoveryAgv(para),
                HikRcsConst.genCtuGroupTaskBatch => _hikParabuild.CreatGenCtuGroupTaskBatch(para),
                HikRcsConst.boxApplyPass => _hikParabuild.CreatBoxApplyPass(para),
                HikRcsConst.setTaskPriority => _hikParabuild.CreatSetPriority(para),
                HikRcsConst.bindPodAndBerth => _hikParabuild.CreatBindPodAndBerth(para),
                HikRcsConst.bindPodAndMat => _hikParabuild.CreatBindPodAndMat(para),
                HikRcsConst.lockPosition => _hikParabuild.CreatLockPosition(para),
                HikRcsConst.syncMapDatas => _hikParabuild.CreatSyncMapDatas(para),
                HikRcsConst.queryPodBerthAndMat => _hikParabuild.CreatQueryPodBerthAndMat(para),
                HikRcsConst.blockStgBin => _hikParabuild.CreatBlockStgBin(para),
                HikRcsConst.bindCtnrAndBin => _hikParabuild.CreatBindCtnrAndBin(para),
                HikRcsConst.blockArea => _hikParabuild.CreatBlockArea(para),
                HikRcsConst.clearRoadWay => _hikParabuild.CreatClearRoadWay(para),
                HikRcsConst.getOutPod => _hikParabuild.CreatGetOutPod(para),
                HikRcsConst.returnPod => _hikParabuild.CreatReturnPod(para),
                HikRcsConst.genPreScheduleTask => _hikParabuild.CreatPreScheduleTask(para),
            };
            if (info is null)
            {
                return null;
            }
            result.data = info;
            result.type = (int)OpticalMsgType.call;
            result.reqCode = reqCode;
            return result;
        }
        #endregion
        #region Private 
        #endregion
    }
}
